package com.example.election;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;


/***
 * 基于jdbc的锁
 */
@Service("dbElectionService")
public class DbElectionServiceImpl implements ElectionService {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private DataSource dataSource;

    private Connection connection;

    private PreparedStatement preparedStatement;

    private String sql = "select * from sys_lock where id = 1 for update";

    @Override
    public void doStart() {
        while (true) {
            try {
                connection = this.dataSource.getConnection();
                connection.setAutoCommit(false);
                preparedStatement = connection.prepareStatement(this.sql);
                preparedStatement.execute();
                //如果获取到锁，就跳出循环。
                break;
            } catch (SQLException exx) {
                try {
                    // logger.error("get lock error :" + exx.getMessage());
                } finally {
                    //只能此处关闭连接
                    if (null != connection) {
                        try {
                            connection.rollback();
                        } catch (SQLException e1) {
                            logger.debug("Caught exception during rollback on connection");
                        }
                        try {
                            connection.close();
                        } catch (SQLException e1) {
                            logger.debug("Caught exception while closing connection");
                        }
                        connection = null;
                    }
                }
            } finally {
                //关闭preparedStatement 但是不能关闭链接
                if (null != preparedStatement) {
                    try {
                        preparedStatement.close();
                    } catch (SQLException e) {
                        logger.error(e.getMessage());
                    }
                }
            }
        }
    }

    @Override
    public void doEnd() {
        if (null != preparedStatement) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                logger.error(e.getMessage());
            }
        }
        if (null != connection) {
            try {
                connection.rollback();
            } catch (SQLException e1) {
                logger.debug("Caught exception during rollback on connection");
            }
            try {
                connection.close();
            } catch (SQLException e1) {
                logger.debug("Caught exception while closing connection");
            }
            connection = null;
        }
    }
}
